package cn.ecasoft.service;

import cn.ecasoft.pojo.ClientSocket;
import cn.ecasoft.util.EncryptUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static cn.ecasoft.service.SocketPool.*;

/**
 * @Author: LiangChun
 * @Description: socekt handler
 * @DateTime: 2023/2/23
 **/

@Slf4j
public class SocketHandler {
    @Autowired

    /**
     * 将连接的Socket注册到Socket池中
     * @param socket
     * @return
     */
    public static ClientSocket register(Socket socket) {
        ClientSocket clientSocket = new ClientSocket();
        clientSocket.setSocket(socket);
        try {
            clientSocket.setInputStream(new DataInputStream(socket.getInputStream()));
            clientSocket.setOutputStream(new DataOutputStream(socket.getOutputStream()));
            String uuid = UUID.randomUUID().toString();
            clientSocket.setKey(uuid);
            clientSocket.setCurrentLong(System.currentTimeMillis() / 1000);
            add(clientSocket);
            return clientSocket;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 向指定客户端发送信息
     *
     * @param clientSocket
     * @param message
     */
    public static void sendMessage(ClientSocket clientSocket, String message) {
        if (!exist(clientSocket.getKey())) return;
        try {
            log.info("发送消息到客户端  : " + message);
            clientSocket.getOutputStream().write(message.getBytes(StandardCharsets.ISO_8859_1));
        } catch (IOException e) {
            log.error("发送信息异常：{}", e);
            close(clientSocket);
        }
    }


    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Socket accept = serverSocket.accept();
//            ClientSocket register = register(accept);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
            System.out.println("服务端收到消息：" + bufferedReader.readLine());
            bufferedWriter.write("测试~~~~\r");
            bufferedWriter.flush();
        }

    }

    /**
     * 获取指定客户端的上传信息
     *
     * @param clientSocket
     * @return
     */
    public static void onMessage(ClientSocket clientSocket) {
        byte[] msgByte = new byte[1];

        if (clientSocket.getIsRemoved()) {
            return;
        } else {
            String info = "";
            try {
                while (!clientSocket.getIsRemoved()) {
                    /*try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        log.error(e.getMessage());
                    }*/
                    if (clientSocket.getInputStream().available() > 0) {
                        clientSocket.getInputStream().read(msgByte);
                        String tempStr = EncryptUtil.byte2hex(msgByte);
                        info += tempStr;
                        //已经读完
                        if (clientSocket.getInputStream().available() == 0) {
                            //重置,不然每次收到的数据都会累加起来
                            clientSocket.setMessage(info);
                            break;
                        }
                    }
                    if (isTimeOut(clientSocket, clientSocket.getTimeout())) {
                        clientSocket.setIsRemoved(true);
                        clientSocket.setMessage(null);
                        log.info("心跳超时，主动关闭SocketKey:{}", clientSocket.getKey());
                        close(clientSocket);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                close(clientSocket);
            }
        }


    }

    /**
     * 指定Socket资源回收
     *
     * @param clientSocket
     */
    public static void close(ClientSocket clientSocket) {
        log.info("资源回收开始：{}", Thread.currentThread().getName());
        if (clientSocket != null) {
            log.info("回收SocketKey:{}", clientSocket.getKey());
            remove(clientSocket.getKey());
            Socket socket = clientSocket.getSocket();
            try {
                if (!socket.isInputShutdown()) {
                    socket.shutdownInput();
                }
                if (!socket.isOutputShutdown()) {
                    socket.shutdownOutput();
                }
            } catch (IOException e) {
                log.error("关闭输入输出流异常，{}", e);
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    log.error("关闭socket异常{}", e);
                }
            }
        }
    }


    /**
     * 检测最近一次心跳包发送的时间，判断数据连接状态
     *
     * @param clientSocket
     * @return
     */
    public static boolean isTimeOut(ClientSocket clientSocket, Integer timeout) {
        try {
            Long time = System.currentTimeMillis() / 1000;
            if (time - get(clientSocket.getKey()).getCurrentLong() > timeout) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 发送数据包，判断数据连接状态
     *
     * @param clientSocket
     * @return
     */
    public static boolean isSocketClosed(ClientSocket clientSocket) {
        try {
            clientSocket.getSocket().sendUrgentData(1);
            return false;
        } catch (IOException e) {
            return true;
        }
    }
}
